using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using MinimalistFoodStreet.BackEnd.Infrastructure.Attributes;
using MinimalistFoodStreet.BackEnd.Infrastructure.Dtos.Request.Tables;
using MinimalistFoodStreet.BackEnd.Infrastructure.Dtos.Response;
using MinimalistFoodStreet.BackEnd.Infrastructure.Dtos.Response.Tables;
using MinimalistFoodStreet.BackEnd.Infrastructure.EFCore;
using MinimalistFoodStreet.BackEnd.Server.TableEFCore;
using MinimalistFoodStreet.BackEnd.Server.Server.RequestExtend.Tables;
using MinimalistFoodStreet.BackEnd.Server.Server.ResponseExtend.Tables;
using MinimalistFoodStreet.BackEnd.Server.IServer.Tables;
using MinimalistFoodStreet.BackEnd.Infrastructure.Tools;

namespace MinimalistFoodStreet.BackEnd.Server.Server.Tables
{
    [InjectClass]
    public class BusinesssServer : IBusinesssServer
    {
        private readonly ServerRepository _serverRepository;
        public BusinesssServer(DbContext dbContext)
        {
            _serverRepository = new ServerRepository(dbContext);
        }

        public async Task<ResponseApiDto> AddAsync(RequestCreateBusinesssDto dto)
        {
            if (await _serverRepository.accountsEFCore.Query(d => d.AAccount == dto.phone).AnyAsync())
            {
                return ResponseApiDto.Fail("该账号已存在");
            }
            if (await _serverRepository.accountsEFCore.Query(d => d.APhone == dto.phone).AnyAsync())
            {
                return ResponseApiDto.Fail("手机号已被使用");
            }
            if (dto.password.Length < 6)
            {
                return ResponseApiDto.Fail("密码不能低于6位");
            }
            int affectedRows = 0;
            await _serverRepository.ExecuteInTransactionAsync(async () =>
            {
                // 生成账号
                string salt = Tools.Guid_1();
                Account account = new Account
                {
                    AAccount = dto.phone,
                    AName = Tools.Guid_1(),
                    APhone = dto.phone,
                    APassword = Encrypt.GetMd5Hash(dto.password + salt),
                    ASalt = salt,
                    AEndpoint = "business"
                };
                affectedRows += await _serverRepository.accountsEFCore.AddAsync(account);
                // 添加商家
                Businesss business = dto.ToCreateEntity();
                business.BAccountId = account.AId;
                affectedRows += await _serverRepository.businesssEFCore.AddAsync(business);
            }, () =>
            {
                affectedRows = 0;
                return null;
            });
            return ResponseApiDto.Create(affectedRows);
        }

        public async Task<ResponseApiDto> UpdateAsync(RequestUpdateBusinesssDto dto)
        {
            Businesss business = await _serverRepository.businesssEFCore.Query(d => d.BId == dto.id).SingleOrDefaultAsync();
            if (business == null)
            {
                return ResponseApiDto.Fail("该实例不存在");
            }
            business.BOpenId = dto.openId;
            business.BName = dto.name;
            business.BManagerName = dto.managerName;
            int affectedRows = 0;
            await _serverRepository.ExecuteInTransactionAsync(async () =>
             {
                 // 修改商家
                 affectedRows += await _serverRepository.businesssEFCore.UpdateAsync(business);
                 // 修改账号
                 Account account = await _serverRepository.accountsEFCore.Query(d => d.AId == business.BAccountId).SingleAsync();
                 account.AAccount = dto.phone;
                 account.APhone = dto.phone;
                 // 重置密码
                 if (dto.passwordReset != null)
                 {
                     account.ASalt = Tools.Guid_1();
                     account.APassword = Encrypt.GetMd5Hash(dto.passwordReset + account.ASalt);
                 }
                 affectedRows += await _serverRepository.accountsEFCore.UpdateAsync(account);
             }, () =>
             {
                 affectedRows = 0; return null;
             });

            return ResponseApiDto.Create(affectedRows);
        }

        public async Task<ResponseApiDto> DeleteAsync(RequestDeleteBusinesssDto dto)
        {
            if (!await _serverRepository.businesssEFCore.Query(d => d.BId == dto.id).AnyAsync())
            {
                return ResponseApiDto.Fail("该实例不存在");
            }
            int affectedRows = 0;
            await _serverRepository.ExecuteInTransactionAsync(async () =>
            {
                int accountId = await _serverRepository.businesssEFCore.Query(d => d.BId == dto.id).Select(d => d.BAccountId).SingleAsync();
                // 删除商家
                affectedRows += await _serverRepository.businesssEFCore.Query(d => d.BId == dto.id).ExecuteDeleteAsync();
                // 删除账号
                affectedRows += await _serverRepository.accountsEFCore.Query(d => d.AId == accountId).ExecuteDeleteAsync();
            }, () =>
            {
                affectedRows = 0;
                return null;
            });
            return ResponseApiDto.Create(affectedRows);
        }

        public async Task<ResponseApiDto> DetailAsync(int id)
        {
            Businesss business = await _serverRepository.businesssEFCore.Query(d => d.BId == id).SingleOrDefaultAsync();
            if (business == null)
            {
                return ResponseApiDto.Fail("该实例不存在");
            }
            Account account = await _serverRepository.accountsEFCore.Query(d => d.AId == business.BAccountId).SingleAsync();
            return ResponseApiDto.Ok("数据已获取", business.ToResponseDto(account));
        }

        public async Task<ResponseApiDto> PaginationAsync(int page, int limit, string? key)
        {
            int total = 0;
            List<Businesss> businesss = await _serverRepository.businesssEFCore.Pagination(d => true, false, d => d.BId, out total, page, limit).ToListAsync();
            List<ResponseBusinesssDto> responseBusinesssDtos = new List<ResponseBusinesssDto>();
            for (int i = 0; i < businesss.Count; i++)
            {
                Businesss business = businesss[i];
                Account account = await _serverRepository.accountsEFCore.Query(d => d.AId == business.BAccountId).SingleAsync();
                responseBusinesssDtos.Add(business.ToResponseDto(account));
            }
            return ResponseApiDto.Ok("数据已获取", new { data = responseBusinesssDtos, total = total });
        }
    }
}